#include "A_Config.h"
#include <rom/rtc.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_task_wdt.h"
SettingsManager settings;
URLCode urlcode;

void task_hal_floop(void *)
{
    while (1)
    {
        appManager.update();
        vTaskDelay(10);
    }
}

void task_loop(void *)
{
    while (1)
    {
        if (xSemaphoreTake(hal.screenMutex, 100) == pdTRUE)
        {
            lv_timer_handler(); /* let the GUI do its work */
            xSemaphoreGive(hal.screenMutex);
        }
        if (ESPNow.isStarted())
        {
            ESPNow.update();
        }
        hal.update();
        delay(5);
    }
}

void setup()
{
    hal.canDeepSleepFromAlarm = true;
    esp_task_wdt_init(portMAX_DELAY, false);
    Serial.begin(115200);
    settings.readSettings(CONFIG_FILE_NAME);
    if (settings.getBool("Available", false) == false)
    {
        settings.loadJson("{}");
        settings.setBool("Available", true);
        settings.writeSettings(CONFIG_FILE_NAME);
    }
    hal.Brightness = settings.getInt("settings.brightness", CONFIG_DEFAULT_BRIGHTNESS);
    printer.setHeatIntensity(settings.getInt("settings.printdensity", 40) * 100);
    hal.initHardware();
    ESPNow.init();
    weather.begin();
    WiFiMgr.begin();
    microKB.begin();
    uint8_t *printData;
    printData = (uint8_t *)ps_malloc(PRINTER_BUFFER_SIZE);
    printer.setBuffer(printData);
#ifdef RTC_IS_DS3231
    hal.rtc.getAll();
#else
    hal.rtc.getTime();
    hal.rtc.getDate();
#endif
    if (!alarm_load())
    {
        alarm_erase();
    }
    alarm_sort();

    if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET && rtc_get_reset_reason(1) != DEEPSLEEP_RESET)
    {
        xSemaphoreTake(hal.wiremutex, portMAX_DELAY);
        // hal.rtc.alarmActive();
#ifdef RTC_IS_DS3231
        hal.rtc.checkIfAlarm(1);
        hal.rtc.checkIfAlarm(2);
        hal.rtc.turnOffAlarm(2);
        hal.rtc.enable32kHz(false);
#else
        hal.rtc.clearAlarm();
        hal.rtc.clearSquareWave();
#endif
        xSemaphoreGive(hal.wiremutex);
        alarm_update();
    }
    if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_UNDEFINED)
    {
        struct timeval tv;
        struct tm t = {0};              // Initalize to all 0's
        t.tm_year = hal.rtc.year + 100; // This is year-1900, so 121 = 2021
        t.tm_mon = hal.rtc.month - 1;
        t.tm_mday = hal.rtc.day;
        t.tm_hour = hal.rtc.hour;
        t.tm_min = hal.rtc.minute;
        t.tm_sec = hal.rtc.sec;
        tv.tv_sec = mktime(&t);  // epoch time (seconds)
        tv.tv_usec = 0;          // microseconds
        settimeofday(&tv, NULL); // set time
    }
    appManager.gotoDefaultApp();
    xTaskCreatePinnedToCore(task_hal_floop, "HAL_fLoop", 10240, NULL, 5, NULL, 1);
    xTaskCreatePinnedToCore(task_loop, "arduino_loop", 8192, NULL, 1, NULL, 1);
    vTaskDelete(NULL);
}
void loop() { vTaskDelay(portMAX_DELAY); }